/**
 * 收藏数据模型
 * @author HalRui
 * @version 1.0.0
 * @description 基于Mongoose的收藏数据模型，定义用户收藏视频的数据结构、验证规则和操作方法，支持收藏夹分类
 * @date 2025年9月27日
 */

const mongoose = require('mongoose');
const { connectDB } = require('../utils/db');

// 收藏模式定义
const favoriteSchema = new mongoose.Schema({
    favoriteId: {
        type: Number,
        required: true,
        description: '收藏记录的唯一标识符，自动递增生成'
    },
    userId: {
        type: Number,
        required: true,
        ref: 'UserInfos',
        description: '收藏用户的ID，关联到用户信息表'
    },
    videoId: {
        type: Number,
        required: true,
        ref: 'Videos',
        description: '被收藏视频的ID，关联到视频表'
    },
    collectionId: {
        type: Number,
        default: null,
        ref: 'Collections',
        description: '收藏夹ID，null表示默认收藏夹，否则为自定义收藏夹ID'
    },
    isDeleted: {
        type: Boolean,
        default: false,
        description: '软删除标记，true表示已删除，false表示正常状态'
    },
    createAt: {
        type: Date,
        default: Date.now,
        description: '收藏记录的创建时间'
    },
    updateAt: {
        type: Date,
        default: Date.now,
        description: '收藏记录的最后更新时间'
    }
});

// 创建索引
favoriteSchema.index({ userId: 1, videoId: 1 }, { unique: true });
favoriteSchema.index({ userId: 1, createAt: -1 });
favoriteSchema.index({ videoId: 1, createAt: -1 });
favoriteSchema.index({ collectionId: 1, createAt: -1 });
favoriteSchema.index({ favoriteId: 1 }, { unique: true });

// 自动递增favoriteId的中间件
favoriteSchema.pre('save', async function(next) {
    if (this.isNew) {
        try {
            const lastFavorite = await this.constructor.findOne({}, {}, { sort: { favoriteId: -1 } });
            this.favoriteId = lastFavorite ? lastFavorite.favoriteId + 1 : 1;
        } catch (error) {
            return next(error);
        }
    }
    this.updateAt = new Date();
    next();
});

// 静态方法：添加收藏
favoriteSchema.statics.addFavorite = async function(favoriteData) {
    await connectDB();
    
    const { userId, videoId, collectionId } = favoriteData;
    
    // 验证必要字段
    if (!userId || !videoId) {
        throw new Error('用户ID和视频ID不能为空');
    }
    
    // 检查是否已经收藏
    const existingFavorite = await this.findOne({ 
        userId, 
        videoId, 
        isDeleted: false 
    });
    
    if (existingFavorite) {
        throw new Error('已经收藏过此视频');
    }
    
    const favorite = new this({
        userId,
        videoId,
        collectionId: collectionId || null
    });
    
    const savedFavorite = await favorite.save();
    
    // 更新视频的收藏数
    const Videos = mongoose.model('Videos');
    await Videos.updateOne(
        { videoId: videoId },
        { $inc: { favoriteCount: 1 } }
    );
    
    return savedFavorite;
};

// 静态方法：取消收藏
favoriteSchema.statics.removeFavorite = async function(userId, videoId) {
    await connectDB();
    
    const favorite = await this.findOne({ 
        userId, 
        videoId, 
        isDeleted: false 
    });
    
    if (!favorite) {
        throw new Error('收藏记录不存在');
    }
    
    // 软删除
    favorite.isDeleted = true;
    favorite.updateAt = new Date();
    await favorite.save();
    
    // 更新视频的收藏数
    const Videos = mongoose.model('Videos');
    await Videos.updateOne(
        { videoId: videoId },
        { $inc: { favoriteCount: -1 } }
    );
    
    return { success: true };
};

// 静态方法：检查收藏状态
favoriteSchema.statics.checkFavoriteStatus = async function(userId, videoId) {
    await connectDB();
    
    const favorite = await this.findOne({ 
        userId, 
        videoId, 
        isDeleted: false 
    });
    
    return {
        isFavorited: !!favorite,
        favoriteId: favorite ? favorite.favoriteId : null,
        collectionId: favorite ? favorite.collectionId : null,
        createAt: favorite ? favorite.createAt : null
    };
};

// 静态方法：获取用户收藏列表
favoriteSchema.statics.getUserFavorites = async function(options) {
    await connectDB();
    
    const { 
        userId, 
        collectionId = null, 
        page = 1, 
        limit = 20, 
        sortBy = 'createAt', 
        sortOrder = 'desc' 
    } = options;
    
    const query = { 
        userId, 
        isDeleted: false 
    };
    
    if (collectionId !== undefined) {
        query.collectionId = collectionId;
    }
    
    const sortOptions = {};
    sortOptions[sortBy] = sortOrder === 'desc' ? -1 : 1;
    
    const skip = (page - 1) * limit;
    
    const [favorites, total] = await Promise.all([
        this.find(query)
            .sort(sortOptions)
            .skip(skip)
            .limit(limit)
            .lean(),
        this.countDocuments(query)
    ]);
    
    return {
        favorites,
        pagination: {
            page,
            limit,
            total,
            pages: Math.ceil(total / limit)
        }
    };
};

// 静态方法：获取视频收藏列表
favoriteSchema.statics.getVideoFavorites = async function(options) {
    await connectDB();
    
    const { videoId, page = 1, limit = 20 } = options;
    
    const skip = (page - 1) * limit;
    
    const [favorites, total] = await Promise.all([
        this.find({ videoId, isDeleted: false })
            .sort({ createAt: -1 })
            .skip(skip)
            .limit(limit)
            .lean(),
        this.countDocuments({ videoId, isDeleted: false })
    ]);
    
    return {
        favorites,
        pagination: {
            page,
            limit,
            total,
            pages: Math.ceil(total / limit)
        }
    };
};

// 静态方法：批量检查收藏状态
favoriteSchema.statics.batchCheckFavoriteStatus = async function(userId, videoIds) {
    await connectDB();
    
    if (!Array.isArray(videoIds) || videoIds.length === 0) {
        return {};
    }
    
    const favorites = await this.find({ 
        userId, 
        videoId: { $in: videoIds }, 
        isDeleted: false 
    }).lean();
    
    const statusMap = {};
    videoIds.forEach(videoId => {
        statusMap[videoId] = false;
    });
    
    favorites.forEach(favorite => {
        statusMap[favorite.videoId] = {
            isFavorited: true,
            favoriteId: favorite.favoriteId,
            collectionId: favorite.collectionId,
            createAt: favorite.createAt
        };
    });
    
    return statusMap;
};

// 静态方法：移动收藏到其他收藏夹
favoriteSchema.statics.moveFavorite = async function(favoriteId, userId, newCollectionId) {
    await connectDB();
    
    const favorite = await this.findOne({ 
        favoriteId, 
        userId, 
        isDeleted: false 
    });
    
    if (!favorite) {
        throw new Error('收藏记录不存在');
    }
    
    favorite.collectionId = newCollectionId;
    favorite.updateAt = new Date();
    await favorite.save();
    
    return favorite;
};

// 静态方法：获取收藏统计
favoriteSchema.statics.getFavoriteStats = async function(userId) {
    await connectDB();
    
    const [totalCount, defaultCollectionCount, customCollectionCount] = await Promise.all([
        this.countDocuments({ userId, isDeleted: false }),
        this.countDocuments({ userId, collectionId: null, isDeleted: false }),
        this.countDocuments({ userId, collectionId: { $ne: null }, isDeleted: false })
    ]);
    
    return {
        totalCount,
        defaultCollectionCount,
        customCollectionCount
    };
};

// 实例方法：获取安全的JSON数据
favoriteSchema.methods.getSafeJSON = function() {
    const favorite = this.toObject();
    delete favorite._id;
    delete favorite.__v;
    return favorite;
};

const Favorites = mongoose.model('Favorites', favoriteSchema);

module.exports = Favorites;